#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define BUFFER_SIZE 5

int buffer[BUFFER_SIZE];
int count = 0;

// 初始化锁
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// 初始化条件变量
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

// 生产者线程
void *producer(void *arg)
{
    int item = 1;
    while (1)
    {
        // 加锁（获取互斥锁 拿不到等，拿到向下执行，其它线程不能进入）
        pthread_mutex_lock(&mutex);

        // 如果缓冲区满，等消费者读取
        while (count == BUFFER_SIZE)
        {
            // 暂停线程 等待唤醒
            pthread_cond_wait(&cond, &mutex);
        }

        // 出while说明缓冲区没满
        // 向缓存区添加一个数据
        buffer[count++] = item++;

        printf("生产者向第%d位添加一个数据：%d\n", count - 1, buffer[count - 1]);

        // 唤醒消费者，可以消费数据了
        pthread_cond_signal(&cond);

        // 释放锁（其它线程可以进入了）
        pthread_mutex_unlock(&mutex);
    }
}

// 消费者线程
void *consumer(void *arg)
{
    while (1)
    {
        // 加锁
        pthread_mutex_lock(&mutex);

        // 如果缓冲区为空，则等待生产者生产数据
        while (count == 0)
        {
            // 暂停线程 等待唤醒
            pthread_cond_wait(&cond, &mutex);
        }

        --count;
        printf("消费者从第%d位读取出一个数据 %d\n", count, buffer[count]);

        // 唤醒生产者，可以开始生产数据了
        pthread_cond_signal(&cond);

        // 释放锁
        pthread_mutex_unlock(&mutex);
    }
}
int main()
{
    pthread_t producer_thread, consumer_thread;
    // 创建生产者和消费都线程
    pthread_create(&producer_thread, NULL, producer, NULL);
    pthread_create(&consumer_thread, NULL, consumer, NULL);
    // 等待2个线程执行完
    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);

    return 0;
}